#pragma once


#pragma once


#include <string>
#include <iostream>
using namespace std;
class Expr;


class Ex_node {

	friend class Expr;
public:
	virtual void print(ostream& o) = 0;

};



class Expr {

	friend ostream& operator<<(ostream&, const Expr&);
	Ex_node* p;
public:

	Expr(int);
	Expr(const string&, Expr);
	Expr(const string&, Expr, Expr);
	//Expr(const string&, Expr, Expr, Expr);
	Expr() {
	}

};



class Int_node : public Ex_node {
	friend class Expr;
	int n;
	Int_node(int k) : n(k) { }
	void print(ostream& o)  { o << n; }
};


class Unary_node :public Ex_node {
	friend class Expr;
	Expr opnd;
	string op;
public:

	Unary_node(string ops, Expr node):opnd(node),op(ops) {
	
	}

	void print(ostream& o) {

		//这里不用ostream似乎没法写
		//cout << left << "" << op << right;
		o << "("<<  op << right << ")";
	}
};


class Binary_node :public Ex_node {
	friend class Expr;
	Expr left;
	Expr right;
	string op;

public:
	friend class Expr;
	Binary_node(string ops, Expr node1, Expr node2) :left(node1), right(node2), op(ops) {

	}
	void print(ostream &o) {
		
		//这里不用ostream似乎没法写
		//cout << left << "" << op << right;
		o << "(" << left << op << right << ")";
	}
};
